#include<iostream>
#include<vector>
#include<algorithm>

//#define ONLINE_JUDGE
#define NO_DEBUG

using namespace std;

typedef unsigned long uint32;
typedef uint32 label_nodo;
typedef uint32 peso;

struct arista_t {
	arista_t(label_nodo a, label_nodo b, peso c): u(a), v(b), P(c) {};
	
	label_nodo u;
	label_nodo v;
	peso P;
};


class Grafo //no orientado
{
	public:
		Grafo (uint32 cant_nodos): E()
			{
				this->n = cant_nodos;
				this->m = 0;
				this->peso_grafo = 0;
			};

		/** Requiere: 
			1)  u, v son nodos del grafo
			2)  arista (u,v) no pertenece al grafo
		**/
		void agregarArista( label_nodo u, label_nodo v, peso p)
			{
				arista_t arista(u,v,p);

				(this->E).push_back(arista);
				this->m++;
				this->peso_grafo += p;
			};
		
		//devuelve el peso del AGM, usando el algoritmo de Kruskal
		peso peso_Kruskal();
		
		//devuelve la suma del peso de todas las aristas
		peso peso_Grafo() const
		{
			return this->peso_grafo;
		};
		
		const uint32 cantNodos() const {
			return this->n;
		};
		
		const uint32 cantAristas() const {
			return this->m;
		};
	
	
	private:
		uint32 n, m;	// n: cantidad de nodos
						// m: cantidad de aristas

		vector<arista_t> E; 
		peso peso_grafo;
			
};

bool compararPeso(const arista_t& a, const arista_t& b)
{
		return a.P < b.P;
}

#define PADRE(i) CC[i]
#define RANK(i) R[i]

label_nodo Find(vector<label_nodo>& CC, label_nodo u)
{
	label_nodo i=u;
	while (PADRE(i) != i)
		i = PADRE(i);
	return PADRE(i);
}

void Union(label_nodo u, label_nodo v, vector<label_nodo>& CC, vector<label_nodo>& R)
{
	if (RANK(u) > RANK(v)) {
		PADRE(v) = u;
	} else
	if (RANK(u) < RANK(v)) {
		PADRE(u) = v;
	}
	else {
		PADRE(v) = u;
		RANK(u) = RANK(u) + 1;		
	}
	
}

#undef PADRE
#undef RANK


peso Grafo::peso_Kruskal()
{

	vector<label_nodo> componentes_Conexas(n);
	vector<label_nodo> rank_Nodos(n,0);
	uint32 cant_Componentes = n;
	
	// MakeSet
	// Inicializa componentes conexas
	for(uint32 i=0; i<n; i++)
		componentes_Conexas[i] = i;
	
	peso peso_AGM = 0;
	
	// Ordena las aristas crecientemente por peso
	sort(E.begin(), E.end(), compararPeso);
	
	vector<arista_t>::iterator it_arista = E.begin();
	label_nodo u, v;
	label_nodo ancestro_u, ancestro_v;
	peso p;
	
	while ((cant_Componentes > 1) && (it_arista != E.end()))
	{
		u = it_arista->u;
		v = it_arista->v;
		p = it_arista->P;
		
		// Find
		// Busca un representante de la componente
		ancestro_u = Find(componentes_Conexas,u);
		ancestro_v = Find(componentes_Conexas,v);
		
		if (ancestro_u != ancestro_v)
		{
			// Union
			// el ancestro de una componente conexa apunta al ancestro de la otra
			Union(ancestro_u, ancestro_v, componentes_Conexas, rank_Nodos);
			
			cant_Componentes--;
			peso_AGM += p;
		}
		
		it_arista++;
	}
	
	return peso_AGM;
}

peso resolver(Grafo &g) {
	return g.peso_Grafo() - g.peso_Kruskal();
}

void resolverDesdeEntrada( istream &entrada, ostream &salida ) {
	int conexiones, rutas;	// m, n	
	int conexion1, conexion2, longitud; // x, y, z
	
	while ( entrada.good() ) {
		entrada >> conexiones >> rutas;
		
		Grafo G(conexiones);

		if ( !entrada.good() || (conexiones==0 && rutas==0))
				break;
		
		for ( int c = 0; c < rutas; c++ ) {

			entrada >> conexion1 >> conexion2 >> longitud;
			
			G.agregarArista(conexion1,conexion2,longitud);
			
		}
		
		salida << resolver(G) << endl;
	}
}

#ifdef ONLINE_JUDGE
int main() {
	resolverDesdeEntrada( cin, cout );
	return 0;
}
#endif
